import 'dart:convert';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:netease_corekit_im/im_kit_client.dart';
import 'package:netease_corekit_im/service_locator.dart';
import 'package:netease_corekit_im/services/login/login_service.dart';
import 'package:nim_chatkit_location/chat_kit_location.dart';
import 'package:nim_chatkit_ui/chat_kit_client.dart';
import 'package:nim_contactkit_ui/contact_kit_client.dart';
import 'package:nim_conversationkit_ui/conversation_kit_client.dart';
import 'package:nim_core/nim_core.dart';
import 'package:nim_searchkit_ui/search_kit_client.dart';
import 'package:nim_teamkit_ui/team_kit_client.dart';
import 'package:yunxin_alog/yunxin_alog.dart';

import 'config.dart';

const channelName = "com.netease.yunxin.app.flutter.im/channel";
const pushMethodName = "pushMessage";

/// description
typedef PushChannelCallBack = void Function(Map? params);

class NimInitial {
  factory NimInitial() => _getInstance();
  static NimInitial get instance => _getInstance();
  static NimInitial? _instance;
  static NimInitial _getInstance() {
    _instance ??= NimInitial._internal();
    return _instance!;
  }

  Uint8List? deviceToken;

  // 应用启动时执行
  //初始化...
  NimInitial._internal() {
    //初始化其他操作...
    debugPrint("NimInitial init");
  }

  /// 初始化IM组件
  void initPlugins() {
    ChatKitClient.init();
    TeamKitClient.init();
    ConversationKitClient.init();
    ContactKitClient.init();
    SearchKitClient.init();

    // IMKitRouter.instance.registerRouter(RouterConstants.PATH_MINE_INFO_PAGE, (context) => const UserInfoPage());
  }

  //初始化位置消息插件
  void initGeoLocation() {
    ChatKitLocation.instance.init(
        aMapAndroidKey: IMDemoConfig.AMapAndroid, aMapIOSKey: IMDemoConfig.AMapIOS, aMapWebKey: IMDemoConfig.AMapWeb);
  }

  /// 获取iOS推送token
  void updateTokenIOS() {
    if (Platform.isIOS) {
      const MethodChannel(channelName).setMethodCallHandler((call) async {
        if (call.method == 'updateAPNsToken') {
          deviceToken = call.arguments as Uint8List;
        }
        return null;
      });
    }
  }

  /// init depends package for app
  void doInitNimSdk(String appKey, {String? account, String? token, Function? succ, Function? failure}) async {
    //如果使用自动登录可在初始化的时候传入loginInfo
    NIMSDKOptions? options;
    if (account == null || token == null) {
      options = await NIMSDKOptionsConfig.getSDKOptions(appKey);
    } else {
      options =
          await NIMSDKOptionsConfig.getSDKOptions(appKey, loginInfo: NIMLoginInfo(account: account, token: token));
    }

    IMKitClient.init(appKey, options).then((success) {
      if (success) {
        startLogin(account: account, token: token, succ: succ, failure: failure);
      } else {
        Alog.d(content: "网易IM初始化失败");
        failure?.call();
      }
    }).catchError((e) {
      Alog.d(content: '网易IM初始化失败原因 ${e.toString()}');
      failure?.call();
    });
  }

  /// 登录IM
  //fixme 将您的云信IM账号(accid)和Token设置在这里即可
  void startLogin({String? account, String? token, Function? succ, Function? failure}) async {
    if (account == null || token == null) {
      return;
    }
    IMKitClient.loginIM(NIMLoginInfo(account: account, token: token)).then((value) {
      if (value) {
        updateAPNsToken();
        succ?.call();
      } else {
        failure?.call();
      }
    });
  }

  /// 更新iOS推送token
  void updateAPNsToken() {
    if (NimCore.instance.isInitialized && Platform.isIOS && deviceToken != null) {
      NimCore.instance.settingsService.updateAPNSToken(deviceToken!, null);
    }
  }

  ///解析从Native端传递过来的消息，并分发
  void handleMessageFromNative({required PushChannelCallBack callback}) {
    const channel = MethodChannel(channelName);

    //注册回调，用于页面没有被销毁的时候的回调监听
    channel.setMethodCallHandler((MethodCall call) async {
      if (call.method == pushMethodName && call.arguments is Map) {
        _dispatchMessage(call.arguments);
        callback(call.arguments);
      }
    });

    //方法调用，用于页面被销毁时候的情况
    channel.invokeMapMethod<String, dynamic>(pushMethodName).then((value) {
      Alog.d(tag: 'HomePage', content: "Message from Native is = $value}");
      _dispatchMessage(value);
      callback(value);
    });
  }

  //分发消息，跳转到聊天页面
  void _dispatchMessage(Map? params) {
    var sessionType = params?['sessionType'] as String?;
    var sessionId = params?['sessionId'] as String?;
    if (sessionType?.isNotEmpty == true && sessionId?.isNotEmpty == true) {
      if (sessionType == 'p2p') {
        // goToP2pChat(context, sessionId!);
      } else if (sessionType == 'team') {
        // goToTeamChat(context, sessionId!);
      }
    }
  }

  //获取pushPayload
  Map<String, dynamic> getPushPayload(NIMMessage message) {
    Map<String, dynamic> pushPayload = {};
    var sessionId =
        message.sessionType == NIMSessionType.p2p ? getIt<LoginService>().userInfo?.userId : message.sessionId;
    var sessionType = message.sessionType == NIMSessionType.p2p ? "p2p" : "team";
    // 添加 apns payload
    // var alert = {
    //   "title" : "your title",
    //   "subtitle" : "your sub Title",
    //   "body" : "your title"
    // };
    // var category = {"category" : "your category"};
    // var apsField = {
    //   "alert":alert,
    //   "category":category
    // };
    // pushPayload["apsField"] = apsField;

    // 添加oppo 的pushPayload
    var oppoParam = {"sessionId": sessionId, "sessionType": sessionType};
    var oppoField = {
      "click_action_type": 4,
      "click_action_activity": 'com.netease.yunxin.app.flutter.im.MainActivity',
      "action_parameters": oppoParam
    };
    pushPayload["oppoField"] = oppoField;
    // 添加vivo 推送参数

    var vivoField = {
      "pushMode": 1 //推送模式 0：正式推送；1：测试推送，不填默认为0
    };

    pushPayload["vivoField"] = vivoField;

    //添加华为推送参数
    var huaweiClickAction = {'type': 1, 'action': 'com.netease.yunxin.app.flutter.im.push'};

    var config = {
      'category': 'IM',
      'data': jsonEncode({'sessionId': sessionId, 'sessionType': sessionType})
    };
    pushPayload['hwField'] = {'click_action': huaweiClickAction, 'androidConfig': config};
    //添加通用的参数
    pushPayload["sessionId"] = sessionId;
    pushPayload["sessionType"] = sessionType;
    return pushPayload;
  }
}
